package xio.ccf_201412;

import java.util.*;

/**
 * 201412-4	最优灌溉 100分
 *
 * 参考算法(第四版) 4.3最小生成树 Prim算法的延时实现
 * 无改动 可直接套用该算法
 * Created by xio on 2017/11/14 0014.
 */
public class OptimalIrrigateLazy {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();

//        构造 Prim算法（延时实现版）

        EdgeWeightedGraph g = new EdgeWeightedGraph(n+1);
        for (int i = 0; i < m; i++) {
            g.addEdge(new Edge(sc.nextInt(),sc.nextInt(),sc.nextInt()));
        }
        LazyPrimMST prim = new LazyPrimMST(g,1);
        System.out.println(prim.weight);
    }


    static class EdgeWeightedGraph{
        private int V;
        private int E;
        private List<LinkedHashSet<Edge>> adj;
        EdgeWeightedGraph(int N){
            this.V = N;
            this.E = 0;
            adj = new ArrayList<>();
            for (int i = 0; i < V; i++) {
                adj.add(new LinkedHashSet<Edge>());
            }
        }

        public void addEdge(Edge e){
            adj.get(e.v).add(e);
            adj.get(e.w).add(e);
            E++;
        }

        public LinkedHashSet<Edge> adj(int v){
            return adj.get(v);
        }

    }

    static class LazyPrimMST {
        private LinkedList<Edge> mst;  //最小生成树的边
        private boolean[] marked;
        private PriorityQueue<Edge> pq;
        private int weight; //最小生成树的边的权重之和

        public LazyPrimMST(EdgeWeightedGraph g, int initV) {
           mst = new LinkedList<>();
            marked = new boolean[g.V];

            pq = new PriorityQueue<>();
            visit(g,initV);

            while (!pq.isEmpty()){
                Edge e = pq.poll();
                int v= e.v;
                int w = e.w;
                if (marked[v] && marked[w]) continue;
                mst.add(e);
                weight+=e.weight;
                if (!marked[v]) visit(g,v);
                if (!marked[w]) visit(g,w);
            }
        }

        private void visit(EdgeWeightedGraph g,int v){
            marked[v] = true;
            for (Edge e : g.adj(v)) {
              if (!marked[e.other(v)]) pq.add(e);
             }
        }

        public LinkedList<Edge> edges(){
            return mst;
        }

        public int weight(){
            return weight;
        }
    }


    static class Edge implements Comparable<Edge>{
        int v,w;
        int weight;

        public Edge(int v, int w, int weight) {
            this.v = v;
            this.w = w;
            this.weight = weight;
        }


        public int other(int x){
            if (x == v) return w;
            else  return v;
        }

        @Override
        public String toString() {
            return "Edge{" +
                    "v=" + v +
                    ", w=" + w +
                    ", weight=" + weight +
                    '}';
        }

        @Override
        public int compareTo(Edge o) {
            if (this.weight > o.weight) return 1;
            else if (this.weight < o.weight) return -1;
            else return 0;
        }
    }
}
